1我们先来看看ArrayList的UML图。
ArrayList继承父类AbstractList及List,Cloneable,Serializable,RandomAccess四个接口。
后四个接口是标记接口,Cloneable提供克隆,Serializable提供序列化,RandomAccess提供快速访问。
List接口提供默认API。
List接口,保留了Collection的一些集合类的基础方法,List接口新增了一些方法,如add(int n,E),get(int),set(int n,E),sort().
AbstractCollection是一个抽象类,对Collection接口部分方法提供了默认实现。
如,isEmpty()方法:
contains(Object o)方法:
o==null的时候调用equals方法报错。
remove(Object e),clear()方法。
AbstrictList对List中的一些新增方法提供了默认实现。
但对于add,set,remove等方法都抛出了UnsupportedOperationException();
具体实现交给子类去覆盖,不能直接用父类来调用(避免用户直接从父类调用,子类可以灵活实现)。
Itr是AbstractList的内部类,继承Iterator接口,为ArrayList的Iterator提供默认实现。
变量cursor存储下一个数组元素index,初始值为0,
lastRet存储上一个数组元素index,初始值为-1,
expectedModCoun数组元素操作次数,初始值为modCount。
hasNext方法。
当下一个index等于集合大小时表示结合为空。
next方法。
取结合中index=cursor中的值,cursor+1,lastRet = cursorOld。
ArrayList继承AbstractList。
ArrayList由数组实现。
(transient表示不参与序列化)。
ArrayList由数组实现,
有3个构造器,无参构造器,有参构造器:
ArrayList(int initialCapacity),ArrayList();
有参构造器,新建一个Object[ ]数组
无参构造器添加一个空数组。
集合构造器,先将集合转换为数组,将数组复制到elementDate中,构成新集合
List的Add方法:
ensureCapacityInternal方法,会先去比较size+1和数组elementData的大小,如果size+1 <= elementDate.length,直接添加,
反之,要先对elementData进行扩容,扩容方法为,
扩大到当前容量的1.5倍,newCapacity = oldCapacity + (oldCapacity >> 1)
新的数组由Arrays.copyof复制得到。
这就是在不知道数组大小的时候建议使用LinkList的原因。
add(int index,E e)插入元素,
和add(E e) 一样,先回去检验数组容量,不过容量不够就扩容到原来的1.5倍,然后执行elementData[index] = e,size++;
小结:
- ArrayList实现了序列化和反序列化,
- ArrayList基于数组实现,无容量的限制(会扩容)
- 添加元素时会扩容,删除元素会减容量,
- 线程不安全